﻿
using System;
namespace Nirvana
{

    public class TimerRepeat : IDisposable
    {
        private float updatetime;

        private float starttime;

        private float delaytime;

        private int loops;
        private int curLoops;

        private bool firstdo;

        private Action mCallback;
        private string name;
        private bool unscaledTime = false;

        /// <summary>
        /// 定时器
        /// </summary>
        /// <param name="name"></param>
        /// <param name="updatetime">定时间隔</param>
        /// <param name="callback">定时回调</param>
        /// <param name="firstdo">立即执行一次</param>
        /// <param name="delaytime">定时器启动时间</param>
        /// <param name="loops">循环次数，-1：永久循环</param>
        /// <param name="unscaledTime">是否受Time.scale影响</param>
        public TimerRepeat(string name, float updatetime, Action callback, bool firstdo, float delaytime, int loops = -1, bool unscaledTime = false)
        {
            this.name = name;
            Init(updatetime, callback, firstdo, delaytime, loops);
        }
        public TimerRepeat(float updatetime, Action callback, bool firstdo, float delaytime, int loops = -1, bool unscaledTime = false)
        {
            this.name = "";
            Init(updatetime, callback, firstdo, delaytime, loops);
        }

        private void Init(float updatetime, Action callback, bool firstdo, float delaytime, int loops = -1, bool unscaledTime = false)
        {
            this.curLoops = 0;
            this.delaytime = delaytime;
            this.updatetime = updatetime;
            this.loops = loops;
            mCallback = callback;
            this.firstdo = firstdo;
            this.unscaledTime = unscaledTime;
            var aliveTime = unscaledTime ? Updater.unscaleAliveTime : Updater.AliveTime;

            if (this.firstdo)
            {
                starttime = aliveTime + delaytime - updatetime;
            }
            else
            {
                starttime = aliveTime + delaytime;
            }
            Register();
        }


        private void Register()
        {
            Updater.AddUpdate(Utils.FormatString("TimerRepeat.{0}", name), OnUpdate, unscaledTime);
        }

        public void UnRegister()
        {
            Updater.RemoveUpdate(Utils.FormatString("TimerRepeat.{0}", name), OnUpdate);
        }

        private void OnUpdate(float delta)
        {
            var aliveTime = unscaledTime ? Updater.unscaleAliveTime : Updater.AliveTime;
            if (aliveTime - starttime >= updatetime)
            {
                if (loops > 0 && this.curLoops >= loops)
                {
                    UnRegister();
                    return;
                }
                starttime += updatetime;
                if (loops > 0)
                {
                    this.curLoops++;
                }
                if (mCallback != null)
                {
                    mCallback();
                }
            }
        }

        public void Dispose()
        {
            UnRegister();
        }
    }
}